package com.gitee.huanminabc.fastboot.load.stage.poststage;

import com.gitee.huanminabc.jcommon.reflect.ClassUtil;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.context.AppContextUtil;
import com.gitee.huanminabc.fastboot.load.hook.DependencyInjectionFinishLifecycleHook;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 依赖注入
 *
 * @program: netty-web
 * @description:
 * @author: huanmin
 * @create: 2025-04-01 11:04
 **/
@Slf4j
public class DependencyInjectionStage implements AppLoadPostStage {

    @Override
    public void run() {
        //获取容器的类
        Set<Map.Entry<Class<?>, Object>> entries = AppContext.containerClassAll.entrySet();
        entries.stream().parallel().forEach(entry -> {
            try {
                //拿到构造参数的参数,如果是空就不处理,这种不用注入
                Constructor<?> maxConstructor = ClassUtil.getMaxConstructor(entry.getKey());
                Class<?>[] parameterTypes = maxConstructor.getParameterTypes();
                if (parameterTypes.length == 0) {
                    return;
                }
                //找到成员是field的然后注入进去
                Class<?> aClass = entry.getKey();
                Object dep = entry.getValue();
                
                //获取构造函数的参数名称集合
                Parameter[] parameters = maxConstructor.getParameters();
                Set<String> constructorParamNames = Arrays.stream(parameters)
                        .map(Parameter::getName)
                        .collect(Collectors.toSet());
                for (String fieldName : constructorParamNames) {
                    Field declaredField = aClass.getDeclaredField(fieldName);
                    //判断是final修饰的 并且是private修饰的, 如果不是那么就不注入
                    if (!Modifier.isFinal(declaredField.getModifiers()) || !Modifier.isPrivate(declaredField.getModifiers()) ) {
                        continue;
                    }
                    AppContextUtil.fieldInject(declaredField, dep);
                }
            } catch (Exception e) {
                 log.error("DependencyInjectionStage:",e);
                 System.exit(1);
            }
        });
        log.debug("DependencyInjectionStage load success");
        //运行加载依赖注入完成的钩子
        new DependencyInjectionFinishLifecycleHook().run();

        //唤醒容器初始化
        synchronized ( ContainerInitCallBackStage.lock){
            ContainerInitCallBackStage.dependencyInjectionStageOk=true;
            ContainerInitCallBackStage.lock.notify();
        }

    }

}
